package com.example.lets;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BaiduMap.OnMapClickListener;
import com.baidu.mapapi.map.BaiduMap.OnMapDoubleClickListener;
import com.baidu.mapapi.map.BaiduMap.OnMapLongClickListener;
import com.baidu.mapapi.map.BaiduMap.OnMapTouchListener;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MarkerOptions.MarkerAnimateType;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.overlayutil.PoiOverlay;
import com.baidu.mapapi.search.core.CityInfo;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult.AddressComponent;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiCitySearchOption;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.poi.PoiDetailSearchOption;
import com.baidu.mapapi.search.poi.PoiNearbySearchOption;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.baidu.mapapi.search.sug.OnGetSuggestionResultListener;
import com.baidu.mapapi.search.sug.SuggestionResult;
import com.baidu.mapapi.search.sug.SuggestionSearch;
import com.baidu.mapapi.search.sug.SuggestionSearchOption;
import com.gc.materialdesign.views.AutoHideButtonFloat;
import com.gc.materialdesign.views.ButtonFloat;
import com.gc.materialdesign.widgets.Dialog;

public class BaiduMapActivity extends Activity implements
        OnGetPoiSearchResultListener, OnGetSuggestionResultListener,
        OnGetGeoCoderResultListener {

    private PoiSearch mPoiSearch = null;
    private SuggestionSearch mSuggestionSearch = null;
    private BaiduMap mBaiduMap = null;
    private MapView mMapView = null;
    /**
     * 搜索关键字输入窗口
     */
    private AutoCompleteTextView keyWorldsView = null;
    private TextView curLoc = null;
    private ArrayAdapter<String> sugAdapter = null;
    private int load_Index = 0;
    private boolean searchInCity = false;

    // 定位相关
    BitmapDescriptor mCurrentMarker;
    LocationClient mLocClient;
    private MyLocationListenner myListener = new MyLocationListenner();
    private String address = null;
    private String detailAddress = null;
    private AddressComponent ac = null;
    private LatLng curLl = null;
    private GeoCoder mSearch = null;

    // 标志
    private Marker myMarker = null;

    // 返回地址的经纬度
    private String latlng = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_baidumap);

        // 初始化搜索模块，注册搜索事件监听
        mPoiSearch = PoiSearch.newInstance();
        mPoiSearch.setOnGetPoiSearchResultListener(this);
        mSuggestionSearch = SuggestionSearch.newInstance();
        mSuggestionSearch.setOnGetSuggestionResultListener(this);
        keyWorldsView = (AutoCompleteTextView) findViewById(R.id.baidumap_searchKey);
        curLoc = (TextView) findViewById(R.id.baidumap_curloc);
        sugAdapter = new ArrayAdapter<>(this,
                android.R.layout.simple_dropdown_item_1line);
        keyWorldsView.setAdapter(sugAdapter);

        mMapView = (MapView) findViewById(R.id.baidumap_view);
        mBaiduMap = mMapView.getMap();

        detailAddress = "";

        ///
        /// spinner
        ///
        Spinner searchRegion = (Spinner) findViewById(R.id.baidumap_searchRegion);
        String[] items = {"周边", "本市"};
        final ArrayAdapter aa = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, items);
        aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        searchRegion.setAdapter(aa);
        searchRegion.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                searchInCity = position == 1;
                TextView tv = (TextView) view;
                tv.setTextColor(Color.BLACK); // 设置颜色
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }

        });

        ///
        /// baidu map
        ///
        // 设定定位模式为普通
        mBaiduMap.setMyLocationConfigeration(new MyLocationConfiguration(
                LocationMode.NORMAL, true, mCurrentMarker));
        // 移除默认的百度LOGO & 缩放按钮 & 比例尺
        View child = mMapView.getChildAt(1);

        if (child instanceof ImageView) child.setVisibility(View.INVISIBLE);
        mMapView.showZoomControls(false);
        mMapView.showScaleControl(false);

        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);

        // 定位初始化
        mLocClient = new LocationClient(this);
        mLocClient.registerLocationListener(myListener);
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true); // 打开gps
        option.setCoorType("bd09ll"); // 设置坐标类型
        option.setScanSpan(0);
        mLocClient.setLocOption(option);
        mLocClient.start();

        // 初始化查询模块
        mSearch = GeoCoder.newInstance();
        mSearch.setOnGetGeoCodeResultListener(this);

        // 初始化地图点击事件
        initListener();

        /**
         * 当输入关键字变化时，动态更新建议列表
         */
        keyWorldsView.addTextChangedListener(new TextWatcher() {

            @Override
            public void afterTextChanged(Editable arg0) {

            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {

            }

            @Override
            public void onTextChanged(CharSequence cs, int arg1, int arg2,
                                      int arg3) {
                if (cs.length() <= 0 || ac == null) {
                    return;
                }
                /**
                 * 使用建议搜索服务获取建议列表，结果在onSuggestionResult()中更新
                 */
                mSuggestionSearch
                        .requestSuggestion((new SuggestionSearchOption())
                                .keyword(cs.toString()).city(ac.city));
            }
        });

        ///
        /// confirm button
        ///
        TextView confirm = (TextView) this.findViewById(R.id.baidumap_confirmAddress);
        confirm.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                String baseAddress = curLoc.getText().toString();
                if (baseAddress == null || baseAddress.equals("")) {
                    Toast.makeText(BaiduMapActivity.this, "基础地址不存在！请重新选择！",
                            Toast.LENGTH_LONG).show();
                    return;
                }
                if (latlng == null) latlng = curLl.longitude + "," + curLl.latitude;
                Dialog dialog = new Dialog(BaiduMapActivity.this, "确定使用以下地址吗", baseAddress);
                dialog.setOnAcceptButtonClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        Intent intent = new Intent();
                        intent.putExtra("latlng", latlng);
                        intent.putExtra("baseAddress", address);
                        intent.putExtra("detailAddress", detailAddress);
                        setResult(RESULT_OK, intent);
                        BaiduMapActivity.this.finish();
                    }
                });
                dialog.show();
            }
        });

        ///
        /// float button
        ///
        ButtonFloat locate = (ButtonFloat) this.findViewById(R.id.baidumap_locate_button);
        locate.setRippleSpeed(10.0f);
        locate.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                mBaiduMap.clear();
                mLocClient.stop();
                mLocClient.start();
            }
        });

    }

    /**
     * 定位SDK监听函数
     */
    public class MyLocationListenner implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {

            ac = null;

            // map view 销毁后不在处理新接收的位置
            if (location == null || mMapView == null) {
                Toast.makeText(BaiduMapActivity.this, "定位服务未开启！", Toast.LENGTH_SHORT).show();
                return;
            }
            int type = location.getLocType();
            if (type != 61 && type != 65 && type != 66 && type != 68 && type != 161) {
                switch (type) {
                    case 62:
                        Toast.makeText(BaiduMapActivity.this, "扫描整合定位依据失败，定位结果无效", Toast.LENGTH_SHORT).show();
                        break;
                    case 63:
                        Toast.makeText(BaiduMapActivity.this, "网络异常，定位失败", Toast.LENGTH_SHORT).show();
                        break;
                    case 67:
                        Toast.makeText(BaiduMapActivity.this, "离线定位失败", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        Toast.makeText(BaiduMapActivity.this, "服务端异常，定位失败", Toast.LENGTH_SHORT).show();
                }
                return;
            }

            curLl = new LatLng(location.getLatitude(), location.getLongitude());

            MapStatus mMapStatus = new MapStatus.Builder().target(curLl).zoom(18).build();
            MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
            mBaiduMap.animateMapStatus(mMapStatusUpdate);

            MarkerOptions mo = new MarkerOptions().position(curLl).icon(
                    BitmapDescriptorFactory.fromResource(R.drawable.icon_marka))
                    .zIndex(9).draggable(false);
            mo.animateType(MarkerAnimateType.drop);
            myMarker = (Marker) mBaiduMap.addOverlay(mo);

            // 获取当前位置的地址
            mSearch.reverseGeoCode(new ReverseGeoCodeOption()
                    .location(curLl));
        }

        public void onReceivePoi(BDLocation poiLocation) {
        }
    }

    private void initListener() {

        mBaiduMap.setOnMapTouchListener(new OnMapTouchListener() {

            @Override
            public void onTouch(MotionEvent event) {

            }
        });

        mBaiduMap.setOnMapClickListener(new OnMapClickListener() {

            public void onMapClick(LatLng point) {

                ac = null;
                // 更新当前位置
                curLl = point;

                mBaiduMap.clear();
                // 在点击位置生成新的Marker
                MarkerOptions mo = new MarkerOptions().position(point).icon(
                        BitmapDescriptorFactory.fromResource(R.drawable.icon_marka))
                        .zIndex(9).draggable(false);
                mo.animateType(MarkerAnimateType.grow);
                myMarker = (Marker) mBaiduMap.addOverlay(mo);

                MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(point);
                mBaiduMap.animateMapStatus(u, 100);

                // 获取点击位置的地址
                mSearch.reverseGeoCode(new ReverseGeoCodeOption().location(point));


            }

            public boolean onMapPoiClick(MapPoi poi) {
                ac = null;
                // 更新当前位置
                LatLng point = poi.getPosition();
                curLl = point;

                detailAddress = poi.getName();
                mBaiduMap.clear();
                // 在点击位置生成新的Marker
                MarkerOptions mo = new MarkerOptions().position(point).icon(
                        BitmapDescriptorFactory.fromResource(R.drawable.icon_marka))
                        .zIndex(9).draggable(false);
                mo.animateType(MarkerAnimateType.grow);
                myMarker = (Marker) mBaiduMap.addOverlay(mo);

                MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(point);
                mBaiduMap.animateMapStatus(u, 100);

                // 获取点击位置的地址
                mSearch.reverseGeoCode(new ReverseGeoCodeOption().location(point));
                return false;
            }
        });

        mBaiduMap.setOnMapLongClickListener(new OnMapLongClickListener() {
            public void onMapLongClick(LatLng point) {

            }
        });

        mBaiduMap.setOnMapDoubleClickListener(new OnMapDoubleClickListener() {
            public void onMapDoubleClick(LatLng point) {

            }
        });
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onDestroy() {
        mPoiSearch.destroy();
        mSuggestionSearch.destroy();
        // 退出时销毁定位
        mLocClient.stop();
        // 关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        mMapView.onDestroy();
        mMapView = null;
        super.onDestroy();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    }

    /**
     * 影响搜索按钮点击事件
     *
     * @param v
     */
    public void searchButtonProcess(View v) {
        if (ac == null) return;

        // cancel focus on edit text
        this.findViewById(R.id.baidumap_searchKey).clearFocus();

        if (searchInCity) {
            mPoiSearch.searchInCity((new PoiCitySearchOption()).city(ac.city)
                    .keyword(keyWorldsView.getText().toString()).pageNum(load_Index));
        } else {
            if (curLl == null) {
                Toast.makeText(this, "定位失败！无法进行周边搜索！", Toast.LENGTH_SHORT).show();
                return;
            }
            mPoiSearch.searchNearby((new PoiNearbySearchOption()).location(curLl).radius(2000)
                    .keyword(keyWorldsView.getText().toString()).pageNum(load_Index));
        }
    }

    public void goToNextPage(View v) {
        load_Index++;
        searchButtonProcess(null);
    }

    public void goToPreviousPage(View v) {
        if (load_Index > 0) {
            load_Index--;
            searchButtonProcess(null);
        }

    }

    public void onGetPoiResult(PoiResult result) {
        if (result == null
                || result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
            Toast.makeText(BaiduMapActivity.this, "未找到结果", Toast.LENGTH_LONG)
                    .show();
            return;
        }
        if (result.error == SearchResult.ERRORNO.NO_ERROR) {
            mBaiduMap.clear();
            PoiOverlay overlay = new MyPoiOverlay(mBaiduMap);
            mBaiduMap.setOnMarkerClickListener(overlay);
            overlay.setData(result);
            overlay.addToMap();
            overlay.zoomToSpan();
            return;
        }
        if (result.error == SearchResult.ERRORNO.AMBIGUOUS_KEYWORD) {

            // 当输入关键字在本市没有找到，但在其他城市找到时，返回包含该关键字信息的城市列表
            String strInfo = "在";
            for (CityInfo cityInfo : result.getSuggestCityList()) {
                strInfo += cityInfo.city;
                strInfo += ",";
            }
            strInfo += "找到结果";
            Toast.makeText(BaiduMapActivity.this, strInfo, Toast.LENGTH_LONG)
                    .show();
        }
    }

    public void onGetPoiDetailResult(PoiDetailResult result) {
        if (result.error != SearchResult.ERRORNO.NO_ERROR) {
            Toast.makeText(BaiduMapActivity.this, "抱歉，未找到结果", Toast.LENGTH_SHORT)
                    .show();
        } else {
            latlng = result.getLocation().longitude + "," + result.getLocation().latitude;
            address = result.getAddress();
            detailAddress = result.getName();
            curLoc.setText(address);
        }
    }

    @Override
    public void onGetSuggestionResult(SuggestionResult res) {
        if (res == null || res.getAllSuggestions() == null) {
            return;
        }
        sugAdapter.clear();
        for (SuggestionResult.SuggestionInfo info : res.getAllSuggestions()) {
            if (info.key != null)
                sugAdapter.add(info.key);
        }
        sugAdapter.notifyDataSetChanged();
    }

    private class MyPoiOverlay extends PoiOverlay {

        public MyPoiOverlay(BaiduMap baiduMap) {
            super(baiduMap);
        }

        @Override
        public boolean onPoiClick(int index) {
            super.onPoiClick(index);
            PoiInfo poi = getPoiResult().getAllPoi().get(index);
            mPoiSearch.searchPoiDetail((new PoiDetailSearchOption()).poiUid(poi.uid));
            return true;
        }
    }


    @Override
    public void onGetGeoCodeResult(GeoCodeResult result) {
        String baseAddress = curLoc.getText().toString();

        if (baseAddress == null || baseAddress.equals("")) {
            Toast.makeText(BaiduMapActivity.this, "基础地址不存在！请重新选择或输入！", Toast.LENGTH_LONG)
                    .show();
            return;
        }
        String latlng = result.getLocation().longitude + "," + result.getLocation().latitude;
        Intent intent = new Intent();
        intent.putExtra("latlng", latlng);
        intent.putExtra("address", address);
        intent.putExtra("detail", detailAddress);
        setResult(RESULT_OK, intent);
        BaiduMapActivity.this.finish();
    }


    @Override
    public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
        if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
            Toast.makeText(BaiduMapActivity.this, "抱歉，未能找到结果", Toast.LENGTH_LONG).show();
            return;
        }
        address = result.getAddress();
        ac = result.getAddressDetail();
        curLoc.setText(address);
    }

    @Override
    public void onBackPressed() {
        Intent intent = new Intent();
        intent.putExtra("address", "点击选取活动地址");
        setResult(RESULT_OK, intent);
        BaiduMapActivity.this.finish();
        return;
    }
}
